import type { WritableAtom } from 'jotai'
import { atom } from 'jotai'
import { atomWithStorage } from 'jotai/utils'
import type { RESET } from 'jotai/vanilla/utils/constants'

type SetStateActionWithReset<Value> = Value | typeof RESET | ((prev: Value) => Value | typeof RESET) // 支持 RESET 的 setState 类型

export default function atomForConfig<T extends Record<string, unknown>>( // config 对象
  key: string,
  defaultValue: T,
): WritableAtom<T, [SetStateActionWithReset<T>], void> {
  // 创建一个支持部分更新和 RESET 的 atom
  const storageAtom = atomWithStorage(key, defaultValue) // 使用 atomWithStorage 创建一个与 localStorage 同步的 atom
  return atom((get) => {
    // 创建一个新的 atom
    // Get the underlying object
    const config = get(storageAtom) // 获取当前的配置对象

    let newConfig: T // 新的配置对象

    // Check if the types are different// 检查类型是否不同
    const isTypeMismatch = typeof config !== typeof defaultValue // 类型不匹配

    if (isTypeMismatch) {
      // 如果类型不匹配，重置为默认值
      newConfig = defaultValue // 重置为默认值
    } else {
      // 类型匹配，检查属性
      // Check if there are missing properties
      let hasMissingProperty = false // 是否有缺失的属性
      for (const key in defaultValue) {
        // 遍历默认值的属性
        if (!(key in config)) {
          // 如果当前配置对象中没有该属性
          hasMissingProperty = true // 标记为缺失属性
          break
        }
      }

      newConfig = hasMissingProperty ? { ...defaultValue, ...config } : config // 如果有缺失属性，合并默认值和当前配置对象，否则保持不变
    }

    if (newConfig !== config) {
      // 如果新的配置对象与当前的不同，更新 localStorage
      const jsonString = JSON.stringify(newConfig)
      localStorage.setItem(key, jsonString)
    }

    return newConfig // 返回新的配置对象
  }, storageAtom.write) // 使用 storageAtom 的写入函数作为新的 atom 的写入函数
}
